HJS

코드 분할 & 지연 로딩

코드 분할(Code Splitting)

코드 분할은 하나의 큰 번들 파일을 여러 개의 작은 파일로 나누는 기법입니다. 페이지나 기능에 필요한 리소스만 로드되도록 하여, 초기 페이지 로딩 시간을 단축시키고 사용자 경험을 향상시킬 수 있습니다.

코드 분할을 구현하기 위해서는 동적 import가 필수적입니다. 동적 import는 특정 컴포넌트나 모듈을 사용자가 필요할 때 비동기적으로 로드할 수 있게 도와줍니다. 예를 들어 사용자가 특정 페이지를 요청했을 때 그 페이지에 필요한 코드만 로드하도록 할 수 있는 방식이 바로 동적 import입니다.

동적 import (Dynamic Import)

동적 import는 필요한 시점에 모듈을 비동기적으로 로드하는 방법입니다. import() 함수는 Promise를 반환하므로, 이를 활용해 비동기적으로 컴포넌트를 로드할 수 있습니다.

const ListPage = lazy(() => import('./pages/ListPage/index'));
const ViewPage = lazy(() => import('./pages/ViewPage/index'));

이렇게 하면 ListPage가 바로 로드되는게 아니라 Promise 객체인 Promise<ListPage>를 반환합니다.

React에서의 동적 import 활용

React에서는 lazy()Suspense를 사용하여 동적 import를 쉽게 구현할 수 있습니다. lazy()는 컴포넌트를 동적으로 로드하도록 Promise객체를 컴포넌트로 반환합니다. Suspense는 로딩 중일 때 대체 UI(스피너 ,메시지 등)을 표시합니다.

사용 예시

import React, { Suspense, lazy } from 'react';
import { Switch, Route } from 'react-router-dom';
import './App.css';

// 동적 import로 컴포넌트 로드
const ListPage = lazy(() => import('./pages/ListPage/index'));
const ViewPage = lazy(() => import('./pages/ViewPage/index'));

function App() {
  return (
    <div className="App">
      <Suspense fallback={<div>로딩 중...</div>}>
        <Switch>
          <Route path="/" component={ListPage} exact />
          <Route path="/view/:id" component={ViewPage} exact />
        </Switch>
      </Suspense>
    </div>
  );
}

export default App;
  1. import('./pages/ListPage/index')Promise<ListPage>를 반환합니다.
  2. lazy()는 이 Promise를 받아 React에서 사용할 수 있는 컴포넌트 형태로 변환합니다.
  3. 로드된 컴포넌트가 화면에 표시되기 전, 로딩 중 UI가 필요합니다. 이를 위해 Suspensefallback 속성을 사용하여 "로딩 중..."을 표시합니다.

React.lazy() 단독 사용 불가

React.lazy()는 컴포넌트를 비동기적으로 로드하는 방식이기 때문에, 이 컴포넌트를 단독으로 사용할 수 없습니다. Suspense 없이 lazy()를 사용하면, 로딩 상태를 어떻게 관리할지 알 수 없어서 오류가 발생합니다.

import { lazy } from 'react';

const MyComponent = lazy(() => import('./MyComponent'));

function App() {
  return <MyComponent />; // ❌ 오류 발생!
}

export default App;

오류 발생 이유

React.lazy()로 불러온 컴포넌트는 비동기적으로 로드되기 때문에, 로딩 상태를 관리할 방법이 없어 Suspense 없이 사용하면 React는 이를 처리할 수 없습니다.